/**
 * 5+原生下载（适用于Android/HarmonyOS）
 */
export function nativeDownload(url: string, fileName: string) {
  // 检查是否在 5+ Runtime 环境中
  if (typeof plus === 'undefined' || !plus.downloader) {
    console.warn('5+ Runtime 环境不可用，使用 web 下载方式');
    webDownload(url, fileName);
    return;
  }

  const dtask = plus.downloader.createDownload(
    url,
    { filename: `download/${fileName}` }, // 保存到downloads目录
    (d: any, status: number) => {
      if (status === 200) {
        plus.nativeUI?.toast(`文件已保存到: ${d.filename}`);
      } else {
        plus.nativeUI?.alert(`下载失败，错误代码: ${status}`);
        // 失败后尝试使用web下载
        webDownload(url, fileName);
      }
    }
  );
  dtask.start();
}

/**
 * 普通web下载（a标签方式）
 */
export function webDownload(url: string, fileName: string = '') {
  const link = document.createElement('a');
  try {
    link.href = url;
    link.download = fileName;
    link.style.display = 'none';
    document.body.appendChild(link);
    link.click();

    setTimeout(() => {
      document.body.removeChild(link);
      if (url.startsWith('blob:')) {
        window.URL.revokeObjectURL(url);
      }
    }, 100);
  } catch (error) {
    // 如果a标签方式也失败，提示用户
    alert('文件下载失败，请检查网络连接或尝试其他方式下载');
  }
}

/**
 *
 * @param headers 响应头
 * @param fileType 文件后缀名 默认xlsx
 * @returns
 */
export function findFileNameByContentDisposition(
  headers: { [x: string]: any; get: (arg0: string) => any },
  fileType: string = 'xlsx'
) {
  // 从响应头获取文件名
  const contentDisposition = headers['content-disposition'];
  let filename = `${new Date().valueOf()}.${fileType}`; // 默认文件名

  if (contentDisposition) {
    const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
    if (filenameMatch && filenameMatch[1]) {
      filename = filenameMatch[1].replace(/['"]/g, '');
      // 处理UTF-8编码的文件名 (RFC 5987)
      if (filename.startsWith("UTF-8''")) {
        filename = decodeURIComponent(filename.replace("UTF-8''", ''));
      }
    }
  }

  return decodeURIComponent(filename);
}

/**
 * 将Base64数据URL转换为File对象
 * @param dataurl Base64格式的数据URL (例如: "")
 * @param filename 生成的文件名
 * @returns 返回File对象或null(转换失败时)
 * @throws 当缺少必要参数或数据格式不正确时抛出错误
 */
export function Base64toFile(dataurl: string, filename: string): File | null {
  if (!dataurl || !filename) {
    throw new Error('缺少必要参数: dataurl和filename都是必需的');
  }
  try {
    const arr = dataurl.split(',');
    if (arr.length < 2) {
      throw new Error('无效的Base64数据URL格式');
    }
    const mimeMatch = arr[0].match(/:(.*?);/);
    if (!mimeMatch) {
      throw new Error('无法从数据URL中提取MIME类型');
    }
    const mime = mimeMatch[1];
    const bstr = atob(arr[1]);
    const u8arr = new Uint8Array(bstr.length);

    for (let i = 0; i < bstr.length; i++) {
      u8arr[i] = bstr.charCodeAt(i);
    }
    return new File([u8arr], filename, { type: mime });
  } catch (e) {
    console.error('Base64转换失败:', e instanceof Error ? e.message : e);
    return null;
  }
}

/**
 * 将二进制数据流转换为Blob对象
 *
 * @param {ArrayBuffer | Uint8Array} binaryData - 要转换的二进制数据，可以是ArrayBuffer或Uint8Array
 * @param {string} [mimeType='application/octet-stream'] - 生成的Blob的MIME类型，默认为'application/octet-stream'
 * @param {BlobPropertyBag} [options] - 可选的Blob属性配置
 * @returns {Blob} - 返回生成的Blob对象
 *
 * @example
 * // 基本用法
 * const buffer = new ArrayBuffer(8);
 * const blob = binaryToBlob(buffer);
 *
 * // 指定MIME类型
 * const blob2 = binaryToBlob(buffer, 'image/png');
 *
 * // 使用options
 * const blob3 = binaryToBlob(buffer, 'application/pdf', { endings: 'transparent' });
 */
export function binaryToBlob(
  binaryData: ArrayBuffer | Uint8Array,
  mimeType: string = 'application/octet-stream',
  options?: BlobPropertyBag
): Blob {
  if (!binaryData) {
    throw new Error('binaryData参数不能为空');
  }
  // 确保传入的是有效的ArrayBuffer或Uint8Array
  if (!(binaryData instanceof ArrayBuffer) && !(binaryData instanceof Uint8Array)) {
    throw new TypeError('binaryData必须是ArrayBuffer或Uint8Array类型');
  }
  // 如果传入的是Uint8Array，提取其底层的ArrayBuffer
  const data: any = binaryData instanceof Uint8Array ? binaryData.buffer : binaryData;
  try {
    return new Blob([data], {
      type: mimeType,
      ...options,
    });
  } catch (error) {
    console.error('创建Blob失败:', error);
    throw new Error('创建Blob失败');
  }
}

/**
 * 将Blob对象转换为File对象
 *
 * @param {Blob} blob - 要转换的Blob对象
 * @param {string} filename - 生成的File对象的文件名
 * @param {FilePropertyBag} [options] - 可选的File属性配置
 * @returns {File} - 返回生成的File对象
 *
 * @throws {Error} 当blob参数无效时抛出错误
 *
 * @example
 * // 基本用法
 * const blob = new Blob(['Hello, world!'], { type: 'text/plain' });
 * const file = blobToFile(blob, 'example.txt');
 *
 * // 使用options
 * const file2 = blobToFile(blob, 'example.txt', {
 *   type: 'text/plain',
 *   lastModified: Date.now()
 * });
 */
export function blobToFile(blob: Blob, filename: string, options?: FilePropertyBag): File {
  if (!(blob instanceof Blob)) {
    throw new TypeError('blob参数必须是Blob对象');
  }
  if (typeof filename !== 'string' || !filename.trim()) {
    throw new TypeError('filename必须是有效的非空字符串');
  }
  try {
    // 合并options和blob的type（如果options未指定type）
    const mergedOptions: FilePropertyBag = {
      type: blob.type,
      ...options,
    };
    return new File([blob], filename, mergedOptions);
  } catch (error) {
    console.error('Blob转换为File失败:', error);
    throw new Error('Blob转换为File失败');
  }
}
